/**
 * Contact.m by Giraldo Rosales.
 * Visit www.liquidgear.net for documentation and updates.
 *
 * Copyright (c) 2009 Nitrogen Design, Inc. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 **/
#if LG_USE_CONTACTS

#import <AddressBook/AddressBook.h>
#import "Contact.h"
#import "WebController.h"

@implementation Contact

@synthesize addressBook, viewController;

- (id)initWithController:(WebController*)controller {
	//self = [super init];
	viewController	= controller;
	addressBook			= ABAddressBookCreate();
	return self;
}

- (void) getContacts:(NSString *)what category:(NSString *) category sort:(NSString *) sort {
	NSMutableArray *contactList					= [NSMutableArray arrayWithCapacity:0];
	NSMutableDictionary *contactDetails	= [NSMutableDictionary dictionaryWithCapacity:0];
	CFArrayRef people;
	
	//Search for contact
	if(category != nil) {
		if([category isEqualToString:@"search"]) {
			people	= ABAddressBookCopyPeopleWithName(self.addressBook,  (CFStringRef)what);
		}
	}
	//Get all contacts
	else {
		people	= ABAddressBookCopyArrayOfAllPeople(self.addressBook);
	}
	
	CFStringRef cFirst, cLast, cMiddle, cPrefix, cSuffix, cNick, cOrg, cTitle, cType, cDept, cNote;
	CFDateRef cBday, cCreated, cModified;
	
	NSArray *multiProp = [NSArray arrayWithObjects:@"type", @"phone", @"email", @"url", @"im", @"date", @"address", nil];
	NSArray *multiArray;
	int numProp			= [multiProp count];
	int numOfPeople	= CFArrayGetCount(people);
	
	//Sort Names
	CFRange fullRange = CFRangeMake(0, numOfPeople);
	CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(people), people);
	
	if([sort isEqualToString:@"first"]) {
		CFArraySortValues(peopleMutable, fullRange, (CFComparatorFunction)ABPersonComparePeopleByName, (ABPropertyID *)kABPersonCompositeNameFormatFirstNameFirst);
	} else {
		CFArraySortValues(peopleMutable, fullRange, (CFComparatorFunction)ABPersonComparePeopleByName, (ABPropertyID *)kABPersonCompositeNameFormatLastNameFirst);
	}
	
	for (int i=0; i<numOfPeople; i++) { 
		bool tagPerson			= NO;
		ABRecordRef person	= (ABRecordRef *) CFArrayGetValueAtIndex(peopleMutable, i);
		
		//Clear temp arrays
		[contactDetails removeAllObjects];
		
		cFirst		= ABRecordCopyValue(person, kABPersonFirstNameProperty);
		cLast			= ABRecordCopyValue(person, kABPersonLastNameProperty);
		cMiddle		= ABRecordCopyValue(person, kABPersonMiddleNameProperty);
		cPrefix		= ABRecordCopyValue(person, kABPersonPrefixProperty);
		cSuffix		= ABRecordCopyValue(person, kABPersonSuffixProperty);
		cNick			= ABRecordCopyValue(person, kABPersonNicknameProperty);
		cOrg			= ABRecordCopyValue(person, kABPersonOrganizationProperty);
		cTitle		= ABRecordCopyValue(person, kABPersonJobTitleProperty);
		cType			= ABRecordCopyValue(person, kABPersonKindProperty);
		cDept			= ABRecordCopyValue(person, kABPersonDepartmentProperty);
		cNote			= ABRecordCopyValue(person, kABPersonNoteProperty);
		
		cBday			= ABRecordCopyValue(person, kABPersonBirthdayProperty);
		cCreated	= ABRecordCopyValue(person, kABPersonCreationDateProperty);
		cModified	= ABRecordCopyValue(person, kABPersonModificationDateProperty);
				
		//Get multiple type
		for(int g=0; g<numProp; g++) {
			multiArray = [self getMultipleValue:person name:[multiProp objectAtIndex:g] filter:what];
			[contactDetails setObject:[multiArray objectAtIndex:0] forKey:[multiProp objectAtIndex:g]];
			if([[multiArray objectAtIndex:1] isEqualToString:@"true"]) {
				tagPerson = TRUE;
			}
		}
 
		if (cFirst != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cFirst] forKey:@"firstName"];
		}
				
		if (cLast != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cLast] forKey:@"lastName"];
		}
		
		if (cMiddle != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cMiddle] forKey:@"middleName"];
		}
		
		if (cPrefix != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cPrefix] forKey:@"prefix"];
		}
		
		if (cSuffix != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cSuffix] forKey:@"suffix"];
		}
		
		if (cNick != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cNick] forKey:@"nickName"];
		}
		
		if (cOrg != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cOrg] forKey:@"org"];
		}
		
		if (cTitle != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cTitle] forKey:@"title"];
		}
		
		if (cType != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cType] forKey:@"type"];
		}
		
		if (cDept != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cDept] forKey:@"dept"];
		}
		
		if (cBday != nil) {
			NSString *fBday	= [[[Utils alloc] autorelease] dateInFormat:@"short" date:cBday];
			[contactDetails setObject:fBday forKey:@"birthday"];
		}
		
		if (cNote != nil) {
			[contactDetails setObject:[NSString stringWithFormat:@"%@", cNote] forKey:@"note"];
		}
		
		if (cCreated != nil) {
			NSString *fCreated	= [[[Utils alloc] autorelease] dateInFormat:@"short" date:cCreated];
			[contactDetails setObject:fCreated forKey:@"created"];
		}
		
		if (cModified != nil) {
			NSString *fModified	= [[[Utils alloc] autorelease] dateInFormat:@"short" date:cModified];
			[contactDetails setObject:fModified forKey:@"modified"];
		}
		
		if((what == nil && category == nil) || [category isEqualToString:@"search"]){
			tagPerson = YES;
		} else {
			if([category isEqualToString:@"firstName"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cFirst]]) {
				tagPerson = YES;
			}
			else if([category isEqualToString:@"lastName"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cLast]]) {
				tagPerson = YES;
			}
			else if([category isEqualToString:@"nickName"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cNick]]) {
				tagPerson = YES;
			}
			else if([category isEqualToString:@"org"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cOrg]]) {
				tagPerson = YES;
			}
			else if([category isEqualToString:@"dept"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cDept]]) {
				tagPerson = YES;
			}
			else if([category isEqualToString:@"title"] && [what isEqualToString:[NSString stringWithFormat:@"%@", cTitle]]) {
				tagPerson = YES;
			}
		}
		
		if(tagPerson) {
			[contactList addObject:contactDetails];
		}
	}
	
	NSDictionary *callback = [NSDictionary dictionaryWithObjectsAndKeys:
														contactList, @"contacts",
														nil
														];
	
	[[[Utils alloc] autorelease] jsCall:viewController.webView type:@"contacts" data:callback directCall:nil];
}

- (void) addContact {
	/*
	ABRecordRef person = ABPersonCreate();
	ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABPersonPhoneProperty);
	
	ABMultiValueAddValueAndLabel(phoneNumberMultiValue, phone, kABPersonPhoneMobileLabel, NULL);
	
	ABRecordSetValue(person, kABPersonLastNameProperty,lName, nil);
	ABRecordSetValue(person, kABPersonFirstNameProperty,fName, nil);
	ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
	
	ABAddressBookAddRecord(addressBook, person, nil);
	ABAddressBookSave(addressBook, nil);
	
	CFRelease(person);
	 */
}

- (ABAddressBookRef)getAddressBook {
	if (!addressBook) {
		addressBook = ABAddressBookCreate();
	}
	return addressBook;
}

- (NSArray *) getMultipleValue:(ABRecordRef) person name:(NSString *)name filter:(NSString *)filter {
	NSMutableArray *contactArray		= [NSMutableArray arrayWithCapacity:0];
	NSMutableDictionary *contactObj	= [NSMutableDictionary dictionaryWithCapacity:0];
	ABMultiValueRef valRef;
	bool nilRef	= FALSE;
	
	if([name isEqualToString:@"phone"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonPhoneProperty);
		nilRef	= TRUE;
	}
	else if([name isEqualToString:@"email"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonEmailProperty);
		nilRef	= TRUE;
	}
	else if([name isEqualToString:@"url"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonURLProperty);
		nilRef	= TRUE;
	}
	else if([name isEqualToString:@"im"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonInstantMessageProperty);
		nilRef	= TRUE;
	}
	else if([name isEqualToString:@"dates"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonDateProperty);
		nilRef	= TRUE;
	}
	else if([name isEqualToString:@"address"]) {
		valRef	= (ABMultiValueRef) ABRecordCopyValue(person, kABPersonAddressProperty);
		nilRef	= TRUE;
	}
	
	NSString *tagOut		= @"false";
	
	if(nilRef) {
		int numMulti			= ABMultiValueGetCount(valRef);
		NSString *refName;
		NSString *refLabel;
		
		for (int g=0; g<numMulti; g++) {
			refLabel	= [self formatLabel:(CFStringRef) ABMultiValueCopyLabelAtIndex(valRef, g)];
			
			if([name isEqualToString:@"address"]) {
				NSDictionary *refDict		= (NSDictionary *) ABMultiValueCopyValueAtIndex(valRef, g);
				
				for (id key in refDict) {
					refLabel	= [self formatLabel:(CFStringRef) key];
					refName		= [refDict objectForKey:key];
					[contactObj setObject:refName forKey:refLabel];
				}
				[contactArray addObject:contactObj];
			} else {
				refName		= (NSString *) ABMultiValueCopyValueAtIndex(valRef, g);
				[contactArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:refName, @"value", refLabel, @"type", nil]];
				
				if([filter isEqualToString:[NSString stringWithFormat:@"%@", refName]]) {
					tagOut = @"true";
				}
			}
		}
	}
	
	NSArray *out = [NSArray arrayWithObjects:contactArray, tagOut, nil];
	return out;
}

- (NSString *) formatLabel:(CFStringRef) label {
	NSString *fLabel;
	
	if (CFStringCompare(label, kABHomeLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"home";
	}
	else if (CFStringCompare(label, kABPersonPhoneMobileLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"mobile";
	}
	else if (CFStringCompare(label, kABWorkLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"work";
	}
	else if (CFStringCompare(label, kABPersonPhoneWorkFAXLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"workFax";
	}
	else if (CFStringCompare(label, kABPersonPhoneMainLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"main";
	}
	else if (CFStringCompare(label, kABPersonPhoneHomeFAXLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"homeFax";
	}
	else if (CFStringCompare(label, kABPersonPhonePagerLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"pager";
	}
	else if (CFStringCompare(label, kABOtherLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"other";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceKey, 0) == kCFCompareEqualTo) {
		fLabel = @"service";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceYahoo, 0) == kCFCompareEqualTo) {
		fLabel = @"yahoo";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceJabber, 0) == kCFCompareEqualTo) {
		fLabel = @"jabber";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceMSN, 0) == kCFCompareEqualTo) {
		fLabel = @"msn";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceICQ, 0) == kCFCompareEqualTo) {
		fLabel = @"icq";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageServiceAIM, 0) == kCFCompareEqualTo) {
		fLabel = @"aim";
	}
	else if (CFStringCompare(label, kABPersonInstantMessageUsernameKey, 0) == kCFCompareEqualTo) {
		fLabel = @"user";
	}
	else if (CFStringCompare(label, kABPersonAnniversaryLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"anniversary";
	}
	else if (CFStringCompare(label, kABPersonHomePageLabel, 0) == kCFCompareEqualTo) {
		fLabel = @"homepage";
	}
	else if (CFStringCompare(label, kABPersonAddressStreetKey, 0) == kCFCompareEqualTo) {
		fLabel = @"street";
	}
	else if (CFStringCompare(label, kABPersonAddressCityKey, 0) == kCFCompareEqualTo) {
		fLabel = @"city";
	}
	else if (CFStringCompare(label, kABPersonAddressStateKey, 0) == kCFCompareEqualTo) {
		fLabel = @"state";
	}
	else if (CFStringCompare(label, kABPersonAddressZIPKey, 0) == kCFCompareEqualTo) {
		fLabel = @"zip";
	}
	else if (CFStringCompare(label, kABPersonAddressCountryKey, 0) == kCFCompareEqualTo) {
		fLabel = @"country";
	}
	else if (CFStringCompare(label, kABPersonAddressCountryCodeKey, 0) == kCFCompareEqualTo) {
		fLabel = @"countryCode";
	} else {
		fLabel = @"na";
	}
	
	return fLabel;
}
@end
#endif